package com.declum.archon.chunkserver.handler.request;

import java.util.ArrayList;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;

import com.declum.archon.client.CreateChunkException;
import com.declum.archon.client.CreateChunkRequest;
import com.declum.archon.client.RequestFactory;
import com.declum.archon.client.RequestType;

public class CreateChunkRequestHandler extends BaseRequestHandler {

	@Override
	public void process(IoSession session, Object msg) throws Exception {
		CreateChunkInfo info = (CreateChunkInfo) session.getAttribute("info");

		if (!info.isAcknowledged()) {
			this.sendAcknowledge(session);
			info.setAcknowledged(true);
			return;
		}
		if (!info.isHeaderRecieved()) {
			byte[] header = this.toByteArray((ByteBuffer) msg);
			info.appendHeaderString(header);
			if (info.isHeaderRecieved()) {
				String key = info.getHeader("key");
				String chunkid = info.getHeader("chunkid");
				String name = info.getHeader("name");

				if (!key.equals(this.server.getClusterID())) {
					this.sendErrorMessage(session, "Cluster ID mismatch");
					session.close();
					return;
				}
				String forwardTo = info.getHeader("forwardTo");
				if (forwardTo != null) {
					String[] mirrors = forwardTo.split(" ");
					String nextLocation;
					ArrayList<String> nextLocations = new ArrayList<String>();
					nextLocation = mirrors[0];
					if (mirrors.length > 1) {
						for (int i = 1; i < mirrors.length; i++) {
							nextLocations.add(mirrors[i]);
						}
					}
					CreateChunkRequest request = (CreateChunkRequest) RequestFactory
							.getInstance().getRequestInstance(
									RequestType.CREATE_CHUNK);

					try {
						System.out.println(info.getHeaders());
						request.connect(nextLocation);
						request
								.createChunk(this.server.getName(), key, name,
										chunkid, nextLocations
												.toArray(new String[] {}));
					} catch (CreateChunkException e) {
						this.sendErrorMessage(session, e.getMessage());
						session.close();
						return;
					} catch (Exception e) {
						this.sendErrorMessage(session, nextLocation
								+ " is dead");
						session.close();
						return;
					}

				}
				this.sendAcknowledge(session);
				session.close();
			}
			return;
		}

	}

	private byte[] toByteArray(ByteBuffer msg) {
		byte[] data = new byte[msg.remaining()];
		msg.get(data, 0, data.length);
		return data;
	}

}
